#pragma once
#include"global.h"
#include<memory>
#include<vector>
#include<string>
#include<tuple>

using namespace std;
class testsetXor
{
protected:
	static int _CmpString(const string& str1,const string& str2,
		int cmp(const char& ch1,const char& ch2));
	static int _CmpString(const string& str1,const string& str2,int mod,
		int cmp(const char& ch1,const char& ch2));
	//which walsh,reversed,compitibility
	static vector<int> _Choose(const string& pattern,const vector<string> hadamard);
	static tuple<int,bool> _Choose(const string& pattern,const vector<string> hadamard,int mod);
	static vector<int> _Choose_multi(const vector<string>&_set,int p,\
const vector<string> hadamard,int in_num);
public:
	testsetXor(void);
	~testsetXor(void);
};



inline int testsetXor::_CmpString(const string& str1,const string& str2,
						   int cmp(const char& ch1,const char& ch2))
{
	int sum=0;
	for(uint32_t i=0;i<str1.length();i++)
		sum+=cmp(str1.at(i),str2.at(i%str2.length()));
	return sum;
}

inline int testsetXor::_CmpString(const string& str1,const string& str2,int mod,
						   int cmp(const char& ch1,const char& ch2))
{
	int sum=0;
	for(uint32_t i=0;i<str1.length();i++)
		sum+=cmp(str1[i],str2[i&mod]);
	return sum;
}

class testsetXor_vertical:public testsetXor
{
private:
	//which vector,is reversed///testset,hadamard order
	static vector<vector<int>> _ChooseSequence(const vector<string>& _set,const vector<string>& hadamard);
	static vector<vector<int>> _ChooseSequence_xyl(vector<string>& _set,const vector<string>& hadamard);
	static vector<vector<int>> _ChooseSequence_multi(const vector<string>& _set,\
const vector<string>& hadamard,int in_num);
public:
	static unique_ptr<string> compress(const vector<string>& _set,int order);
	static unique_ptr<string> compress(const vector<string>& _set,int order,int in_num);
	static unique_ptr<string> compress_lfsr(const vector<string>& _set,int order);
	static unique_ptr<string> compress_multi(const vector<string>& _set,int order,\
int in_num);
	static vector<vector<uint8_t>> choose(const vector<string>& _set,int order);
	static vector<vector<uint8_t>> choose(const vector<string>& _set,int order,int in_num);
	static vector<vector<uint8_t>> choose_multi(const vector<string>& _set,int order,int in_num);
	
	static vector<vector<uint8_t>> choose2(const vector<string>& _set,int order);	
};

class testsetXor_horizontal:public testsetXor
{
private:
	//which vector,is reversed///testset,hadamard order
	static vector<tuple<int,bool>> _ChooseSequence(const string& _set,const vector<string>& hadamard,int L);
public:
	static unique_ptr<string> compress(const string& _set,int order,int L);
};

